package com.egg.common.log.config;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.egg.common.core.model.response.ResponseData;
import com.egg.common.util.HttpServletUtil;
import com.egg.common.util.IpUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.annotation.Order;

import javax.servlet.http.HttpServletRequest;

/**
 * 日志切面
 *
 * @author east
 */
@Profile({"dev", "test", "local"})
@Slf4j
@Order(100)
@Aspect
@Configuration
public class LogsPrint {


    /**
     * 切点
     */
    @Pointcut("execution(* com.egg.*.controller..*.*(..)) || @annotation(io.swagger.annotations.ApiOperation)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object proceed = point.proceed();
        HttpServletRequest request = HttpServletUtil.getHttpServletRequest();
        if (null == request) {
            return proceed;
        }
        try {
            StringBuilder from = new StringBuilder();
            Signature signature = point.getSignature();
            JSONObject jsonParam = HttpServletUtil.parsingRequestParam(point);
            JSONObject jsonHeader = HttpServletUtil.parsingRequestHeader(request);
            String method = "";
            ApiOperation annotation = ((MethodSignature) signature).getMethod().getAnnotation(ApiOperation.class);
            if (null != annotation) {
                method = annotation.value();
            }
            from.append("请求IP: ").append(IpUtil.requestIp()).append("\n")
                    .append("接口请求头: ").append(jsonHeader.toJSONString()).append("\n")
                    .append("接口名称: ").append(method).append("\n")
                    .append("接口类型: ").append(request.getMethod()).append("\n")
                    .append("接口类名: ").append(signature.getDeclaringTypeName()).append(".").append(signature.getName()).append("\n")
                    .append("接口地址: ").append(request.getRequestURI()).append("\n")
                    .append("接口入参: ").append(jsonParam.toJSONString()).append("\n");
            if (proceed instanceof ResponseData) {
                from.append("请求结果: ").append(JSON.toJSONString(proceed)).append("\n")
                        .append("请求时长: ").append((System.currentTimeMillis() - startTime)).append("ms").append("\n");
            } else {
                from.append("请求结果: ").append(proceed).append("\n")
                        .append("请求时长: ").append((System.currentTimeMillis() - startTime)).append("ms").append("\n");
            }
            log.debug("\n请求日志: \n{}", from);
        } catch (Exception e) {
            log.debug("日志切面异常: ", e);
        }
        return proceed;
    }


}
